/*
 * Copyright 2006-2008 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.martinimix.context.support;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.martinimix.domain.content.ContentNotFoundException;

import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.support.MessageSourceAccessor;

import com.bluemartini.dna.BMContext;
import com.bluemartini.dna.BMException;
import com.bluemartini.htmlapp.Content;
import com.bluemartini.htmlapp.HTMLContentUtil;
import com.bluemartini.server.BMAppServer;

/**
 * Provides view macro request context.
 * 
 * @author Scott Rossillo
 * 
 */
public class MartiniMixMacroRequestContext {
	
	private final MessageSourceAccessor messageSourceAccessor;
	private final HttpServletRequest request;
	private HttpServletResponse response;
	
	private final int port;
	private final int securePort;
	
	/**
	 * Creates a new macro request context using the given
	 * message source accessor to resolve messages.
	 * 
	 * @param messageSourceAccessor the <code>MessageSourceAccessor</code>
	 * this class will use to resolve messages
	 * 
	 * @param request the current <code>HttpServletRequest</code>
	 */
	public MartiniMixMacroRequestContext(
			MessageSourceAccessor messageSourceAccessor, 
			HttpServletRequest request) { 
		
		if(messageSourceAccessor == null) {
			throw new IllegalArgumentException("[MessageSourceAccessor] cannot be null!");
		}
		
		if(request == null) {
			throw new IllegalArgumentException("[HttpServletRequest] cannot be null!");
		}
		
		this.messageSourceAccessor = messageSourceAccessor;
		this.request = request;
		
		port = BMContext.getAppConfig().getAsInteger(
				"httpPort", BMAppServer.getAppServer().getDefaultListenPort());

		securePort = BMContext.getAppConfig().getAsInteger(
				"httpsPort", BMAppServer.getAppServer().getDefaultSSLListenPort());
	}
	
	/**
	 * Encodes the given URL using the current HTTP servlet response.
	 * 
	 * @param url the URL to encode
	 * 
	 * @return the encoded version of the given <code>url</code>
	 */
	public String encodeURL(String url) {
		return response.encodeURL(url);
	}
	
	/**
	 * Returns a fully qualified URL for the given URI.
	 * 
	 * @param uri the URI to fully qualify
	 * 
	 * @param secure <code>true</code> to generate an secure URL;
	 * <code>false</code> otherwise
	 * 
	 * @return a fully qualified version of the given <code>uri</code>
	 * after passing through {@link #encodeURL(String)}
	 */
	public String getURL(String uri, boolean secure) {

		final StringBuffer url = new StringBuffer();

		url.append(!secure ? "http://" : "https://");
		url.append(request.getServerName());

		if( (!secure && port != 80) || ( secure && securePort != 443) ) {
			url.append(':');
			url.append(secure ? securePort : port);
		}
		
		url.append(uri);

		return encodeURL(url.toString());
	}
	
	/**
	 * Returns a string containing the versioned URI for the content at
	 * the given content path.
	 * 
	 * @param contentPath the unversioned content path
	 * 
	 * @return the versioned URI to the content at the given
	 * <code>contentPath</code>
	 * 
	 * @throws ContentNotFoundException if the given <code>contentPath</code>
	 * is invalid 
	 */
	public String resolveContentUri(String contentPath) throws ContentNotFoundException {
		
		Content content;
		
		if (contentPath == null) {
            throw new IllegalArgumentException("[contentPath] cannot be null!");
        }
		
		try {
			content = HTMLContentUtil.getContentByName(contentPath);
		} catch (BMException e) {
			throw new ContentNotFoundException("Invalid content path [" + contentPath + "]", e);
		}
				
		return content.getPath();
	}
	
	/**
	 * Returns the message text for the given message source.
	 * 
	 * @param messageSourceResolvable the <code>MessageSourceResolvable</code>
	 * containing the message to be resolved
	 * 
	 * @return the message identified by the given <code>messageSourceResolvable</code>
	 */
	public String resolveMessage(MessageSourceResolvable messageSourceResolvable) {
		
		return messageSourceAccessor.getMessage(messageSourceResolvable);
	}

	/**
	 * Sets the HTTP service response for this request context.
	 * 
	 * @param response the current <code>HttpServletResponse</code>
	 */
	public void setResponse(HttpServletResponse response) {
		this.response = response;
	}
	
}
